package utils

import (
	"fmt"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	zh_translations "github.com/go-playground/validator/v10/translations/zh"
	"reflect"
	"strings"
)

var Trans ut.Translator

type CustomValidator struct {
	Validator *validator.Validate
	Trans     ut.Translator
}

// 实现 gin 的 binding.StructValidator 接口所有方法
var _ binding.StructValidator = &CustomValidator{}

func (cv *CustomValidator) Engine() interface{} {
	return cv.Validator
}

func (cv *CustomValidator) ValidateStruct(obj interface{}) error {
	if err := cv.Validator.Struct(obj); err != nil {
		return cv.translateError(err, obj)
	}
	return nil
}

func (cv *CustomValidator) ValidateTag() string {
	return "validate"
}

// 自定义错误翻译，优先读取 msg 标签
func (cv *CustomValidator) translateError(err error, obj interface{}) error {
	if validationErrors, ok := err.(validator.ValidationErrors); ok {
		for _, e := range validationErrors {
			// 尝试获取结构体的 msg 标签
			if msg := getCustomMsg(e, obj); msg != "" {
				return fmt.Errorf(msg)
			}

			// 没有 msg 标签则使用默认翻译
			return fmt.Errorf(e.Translate(cv.Trans))
		}
	}
	return err
}

// 获取字段的自定义错误消息
func getCustomMsg(e validator.FieldError, obj interface{}) string {
	t := reflect.TypeOf(obj)
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	if field, ok := t.FieldByName(e.Field()); ok {
		if msg := field.Tag.Get("msg"); msg != "" {
			// 处理带参数的情况，如 eqfield=Password
			if e.Param() != "" {
				return strings.ReplaceAll(msg, e.Tag()+"="+e.Param(), "")
			}
			return msg
		}
	}
	return ""
}

// 初始化验证器
func InitValidator() {
	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
		zh := zh.New()
		uni := ut.New(zh, zh)
		Trans, _ = uni.GetTranslator("zh")
		_ = zh_translations.RegisterDefaultTranslations(v, Trans)

		// 注册为Gin的默认验证器
		binding.Validator = &CustomValidator{
			Validator: v,
			Trans:     Trans,
		}
	}
}
